package com.tbit.main.remote.rpc;

import cn.hutool.core.lang.TypeReference;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tbit.Version;
import com.tbit.common.constant.SystemConstant;
import com.tbit.common.entity.TempPowerCheckResult;
import com.tbit.common.utils.TraceUtil;
import com.tbit.main.common.JsonResult;
import com.tbit.main.constant.ResponseCode;
import com.tbit.main.constant.UqbikeManagerConfig;
import com.tbit.main.exception.BaseException;
import com.tbit.main.pojo.*;
import com.tbit.main.util.LogUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;

import java.util.*;

/**
 * 优驱
 *
 * @author Leon
 * 2019年11月17日 上午8:45:54
 */
@Slf4j

public class UQHttpClient {
    private static HttpClient client = null;

    /**
     * 维持单session
     */
    public static HttpClient getClient() {
        if (client == null) {
            MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
            client = new HttpClient(connectionManager);
            /**设置编码*/
            client.getParams().setContentCharset("UTF-8");
            /**请求超时*/
            client.getHttpConnectionManager().getParams().setConnectionTimeout(3000);
            /**读取超时*/
            client.getHttpConnectionManager().getParams().setSoTimeout(5000);

            // uq http 请求客户端设置请求头参数，添加TraceId
            List<org.apache.commons.httpclient.Header> headers = new ArrayList<>();
            headers.add(new org.apache.commons.httpclient.Header(SystemConstant.TRACE_ID, TraceUtil.getTraceIdByLocal()));
            headers.add(new org.apache.commons.httpclient.Header("U-APP-VERSION", Version.VERSION));
            client.getHostConfiguration().getParams().setParameter("http.default-headers", headers);
        }
        return client;
    }

    /**
     * 获取订单金额
     */
    //根据骑行用户，获取订单金额--》调用客户端machine/getFee.do接口--》拼接参数
    public static Integer getOrderMoney(Integer userId) {
        Integer money = null;

        HttpClient client = getClient();
        PostMethod post = null;

        try {
            post = new PostMethod(UqbikeManagerConfig.clientsite + "/machine/getFee.do");
            NameValuePair userIdPair = new NameValuePair("userId", String.valueOf(userId));
            post.setRequestBody(new NameValuePair[]{userIdPair});
            client.executeMethod(post);
            String result = post.getResponseBodyAsString();
            JSONObject object = JSON.parseObject(result);
            LogUtil.info(userId + "获取客户端订单信息=" + result);
            Integer ret = object.getInteger("ret");
            if (ret == 1) {
                if (object.getJSONObject("data") != null && object.getJSONObject("data").getInteger("money") != null) {
                    money = object.getJSONObject("data").getInteger("money");
                }
            }
            LogUtil.info(userId + "订单金额=" + money);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            post.releaseConnection();
        }

        return money;
    }

    /**
     * 发送小程序通知
     *
     * @param rideLog 订单
     */
    public static void sendLockMsg(RideLog rideLog, Integer accountId) {

        LogUtil.info("rideLog推送:" + rideLog.toString());
        Map<String, String> map = new HashMap<>();
        map.put("number1", rideLog.getUserCode());
        map.put("time2", rideLog.getStartTime());
        map.put("thing3", "车辆还有10分钟结束订单");

        String url = UqbikeManagerConfig.clientsite + "/weixinPay/sendLockMsg.do";
        JSONObject jsonObjectTemplate;
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("accountId", accountId);
        jsonObject.put("userId", rideLog.getUserId());
        jsonObject.put("param", map);
        jsonObject.put("type", 2);
        try {
            String data = HttpRequest.post(url)
                    .header(Header.CONTENT_TYPE, "application/json")
                    .header(Header.ACCEPT, "application/json")
                    .timeout(10000)
                    //请求主体
                    .body(JSONObject.toJSONString(jsonObject))
                    .execute().body();
            //结果转成Object对象
            jsonObjectTemplate = JSONObject.parseObject(data);
            LogUtil.info("发送消息模板返回参数" + jsonObjectTemplate);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            LogUtil.error("获取token异常", e);
        }
    }

    /**
     * 获取未支付链接
     *
     * @param accountId 品牌
     */
    public static String WZFlink(Integer accountId) {
        String link = null;

        HttpClient client = getClient();
        PostMethod post = null;

        try {
            post = new PostMethod(UqbikeManagerConfig.clientsite + "/weixinPay/getUrlScheme.do");
            NameValuePair accountIdPair = new NameValuePair("accountId", String.valueOf(accountId));
            NameValuePair typePair = new NameValuePair("type", String.valueOf(17));
            post.setRequestBody(new NameValuePair[]{accountIdPair, typePair});
            client.executeMethod(post);
            String result = post.getResponseBodyAsString();
            JSONObject object = JSON.parseObject(result);
            Integer ret = object.getInteger("ret");
            if (ret == 1) {
                if (object.get("data") != null) {
                    link = object.get("data").toString();
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            LogUtil.info("获取未支付链接失败！");
        } finally {
            post.releaseConnection();
        }

        return link;
    }

    /**
     * 获取垂直停车信息
     */
    public static ClientDate getVert(String userCode, Integer type, Integer parkPointId, Double lon, Double lat) {
        HttpClient client = getClient();
        PostMethod post = null;

        try {
            post = new PostMethod(UqbikeManagerConfig.clientsite + "parkPoint/getVert.do");
            //post = new PostMethod("https://clientv3.uqbike.cn//parkPoint/getVert.do");
            NameValuePair userIdPair = new NameValuePair("userCode", userCode);
            NameValuePair lonPair = new NameValuePair("lon", String.valueOf(lon));
            NameValuePair latPair = new NameValuePair("lat", String.valueOf(lat));
            NameValuePair typePair = new NameValuePair("type", String.valueOf(type));
            if (type == 1) {
                post.setRequestBody(new NameValuePair[]{userIdPair, lonPair, latPair, typePair});
            } else if (type == 2) {
                post.setRequestBody(new NameValuePair[]{userIdPair, typePair});
            }
            client.executeMethod(post);
            String result = post.getResponseBodyAsString();

            JSONObject object = JSON.parseObject(result);
            Integer ret = object.getInteger("ret");
            if (ret == 1) {
                if (type == 1) {
                    ParkPointVertDebug parkPointVertDebug = JSONObject.parseObject(object.getString("data"), ParkPointVertDebug.class);
                    ClientDate<ParkPointVertDebug> debug = new ClientDate<>();
                    debug.setDate(parkPointVertDebug);
                    return debug;
                } else if (type == 2) {
                    SpikeDebug spikeDebug = JSONObject.parseObject(object.getString("data"), SpikeDebug.class);
                    ClientDate<SpikeDebug> debug = new ClientDate<>();
                    debug.setDate(spikeDebug);
                    return debug;
                }
            } else {
                LogUtil.info("调用垂直停车接口成功，返回数据失败");
            }
        } catch (Exception e) {
            LogUtil.info("调用垂直停车接口失败");
            log.error(e.getMessage(), e);
        } finally {
            post.releaseConnection();
        }

        return null;
    }

    /**
     * 获取预估低电的设备
     */
    public static List<Integer> getPower(Integer accountId, String date, Integer power) {
        HttpClient client = getClient();
        PostMethod post = null;

        List spikeDebug = new LinkedList<>();

        try {
            post = new PostMethod(UqbikeManagerConfig.clientip + "intel/statPower.do");
            NameValuePair accountIdPair = new NameValuePair("adAccountId", String.valueOf(accountId));
            NameValuePair datePair = new NameValuePair("date", date);
            NameValuePair powerPair = new NameValuePair("power", String.valueOf(power));
            post.setRequestBody(new NameValuePair[]{accountIdPair, datePair, powerPair});
            client.executeMethod(post);
            String result = post.getResponseBodyAsString();
            JSONObject object = JSON.parseObject(result);
            Integer ret = object.getInteger("ret");
            if (ret == 1) {
                spikeDebug = JSONObject.parseObject(object.getString("data"), List.class);
                LogUtil.info("预估低电接口" + object.get("data"));
                LogUtil.info(spikeDebug + "");
                return spikeDebug;
            } else {
                LogUtil.info("调用预估低电接口成功，返回数据失败");
            }
        } catch (Exception e) {
            LogUtil.info("调用预估低电接口失败");
            log.error(e.getMessage(), e);
        } finally {
            post.releaseConnection();
        }

        return spikeDebug;
    }

    /**
     * 智能调度
     */
    public static List<SmartDispatch> dispatch(Integer accountId, Double lo, Double la, Integer radius, Integer hour, Integer mapType) {
        HttpClient client = getClient();
        PostMethod post = null;

        List<SmartDispatch> smartDispatches = new LinkedList<>();

        try {
            post = new PostMethod(UqbikeManagerConfig.clientip + "intel/dispatch.do");
            NameValuePair accountIdPair = new NameValuePair("adAccountId", accountId + "");
            NameValuePair loPair = new NameValuePair("lo", lo + "");
            NameValuePair laPair = new NameValuePair("la", la + "");
            NameValuePair hourPair = new NameValuePair("hour", String.valueOf(hour));
            NameValuePair radiusPair = new NameValuePair("radius", String.valueOf(radius));
            NameValuePair mapTypePair = new NameValuePair("mapType", String.valueOf(mapType));

            post.setRequestBody(new NameValuePair[]{accountIdPair, loPair, laPair, radiusPair, mapTypePair, hourPair});
            client.executeMethod(post);
            String result = post.getResponseBodyAsString();
            JSONObject object = JSON.parseObject(result);
            Integer ret = object.getInteger("ret");
            if (ret == 1) {
                String data = object.getString("data");
                smartDispatches = JSON.parseArray(data, SmartDispatch.class);
                LogUtil.info("智能调度接口成功" + smartDispatches.toString());
            } else {
                LogUtil.info("智能调度接口成功，返回数据失败");
            }
        } catch (Exception e) {
            LogUtil.info("智能调度接口失败");
            log.error(e.getMessage(), e);
        } finally {
            post.releaseConnection();
        }

        return smartDispatches;
    }

    /**
     * 智能调度订单
     */
    public static List<DispatchRideLog> dispatchRideLog(Integer accountId, String startTime, String endTime) {
        HttpClient client = getClient();
        PostMethod post = null;

        List<DispatchRideLog> dispatchRideLogs = new LinkedList<>();

        try {
            post = new PostMethod(UqbikeManagerConfig.clientip + "intel/getByAccountId.do");
            NameValuePair accountIdPair = new NameValuePair("adAccountId", accountId + "");
            NameValuePair startTimePair = new NameValuePair("startTime", startTime);
            NameValuePair endTimePair = new NameValuePair("endTime", endTime);

            post.setRequestBody(new NameValuePair[]{accountIdPair, startTimePair, endTimePair});
            client.executeMethod(post);
            String result = post.getResponseBodyAsString();
            JSONObject object = JSON.parseObject(result);
            Integer ret = object.getInteger("ret");
            if (ret == 1) {
                String data = object.getString("data");
                dispatchRideLogs = JSON.parseArray(data, DispatchRideLog.class);
                LogUtil.info("智能调度订单接口成功" + dispatchRideLogs.toString());
            } else {
                LogUtil.info("智能调度订单接口成功，返回数据失败");
            }
        } catch (Exception e) {
            LogUtil.info("智能调度订单接口失败");
            log.error(e.getMessage(), e);
        } finally {
            post.releaseConnection();
        }

        return dispatchRideLogs;
    }

    /**
     * 获取一天预估借出车辆数据统计
     */
    public static Client statDay(Integer parkPointId) {
        HttpClient client = getClient();
        PostMethod post = null;
        try {
            post = new PostMethod(UqbikeManagerConfig.clientip + "intel/statDay.do");
            NameValuePair parkPointIdPair = new NameValuePair("parkPointId", String.valueOf(parkPointId));
            post.setRequestBody(new NameValuePair[]{parkPointIdPair});
            client.executeMethod(post);
            String result = post.getResponseBodyAsString();
            JSONObject object = JSON.parseObject(result);
            Integer ret = object.getInteger("ret");
            if (ret == 1) {
                Client hourStatDay = JSONObject.parseObject(object.toString(), Client.class);
                LogUtil.info("结果: " + hourStatDay.toString());
                return hourStatDay;
            } else {
                LogUtil.info("调用一天预估借出车辆接口成功，数据统计失败");
                return null;
            }
        } catch (Exception e) {
            LogUtil.info("调用一天预估借出车辆数据统计失败");
            log.error(e.getMessage(), e);
        } finally {
            post.releaseConnection();
        }

        return null;
    }

    /**
     * 获取垂直停车信息
     */
    public static Integer refresh(String userCode, Integer type) {
        HttpClient client = getClient();
        PostMethod post = null;

        Integer state = 0;

        try {
            post = new PostMethod(UqbikeManagerConfig.clientsite + "parkPoint/refresh.do");
            NameValuePair refreshPair = new NameValuePair("type", String.valueOf(type));
            NameValuePair userCodePair = new NameValuePair("userCode", userCode);
            post.setRequestBody(new NameValuePair[]{userCodePair, refreshPair});
            client.executeMethod(post);
            String result = post.getResponseBodyAsString();
            JSONObject object = JSON.parseObject(result);
            Integer ret = object.getInteger("ret");
            if (ret == 1) {
                state = 1;
                LogUtil.info("调用触发刷新状态成功");
            } else {
                LogUtil.info("调用触发刷新状态成功，返回数据失败");
            }
        } catch (Exception e) {
            LogUtil.info("调用触发刷新状态失败");
            log.error(e.getMessage(), e);
        } finally {
            post.releaseConnection();
        }

        return state;
    }


    /**
     * 查询蓝牙是否支持
     */
    public static Boolean getMachineBluetooth(String userCode) {
        Boolean userStatueData = false;
        HttpClient client = getClient();
        PostMethod post = null;
        try {
            post = new PostMethod(UqbikeManagerConfig.clientsite + "machine/checkNewParkVoice.do");
            NameValuePair userIdPair = new NameValuePair("userCode", String.valueOf(userCode));
            post.setRequestBody(new NameValuePair[]{userIdPair});
            client.executeMethod(post);
            String result = post.getResponseBodyAsString();
            JSONObject object = JSON.parseObject(result);
            LogUtil.info("获取车辆结果=" + result);
            Integer ret = object.getInteger("ret");
            if (ret.equals(1)) {
                userStatueData = object.getBoolean("data");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            post.releaseConnection();
        }
        return userStatueData;
    }

    /**
     * 临时通电检查
     */
    public static TempPowerCheckResult checkTempPower(Map<String, Object> params) {
        String checkTempPowerUrl = UqbikeManagerConfig.clientsite + "/accountSpike/rpc/checkTempPower.do";

        if (log.isInfoEnabled()) {
            log.info("[UQHttpClient][checkTempPower][params: {}]", params);
        }

        String resp = UQHttpUtil.sendGet(checkTempPowerUrl, params);

        if (log.isInfoEnabled()) {
            log.info("[UQHttpClient][checkTempPower][result: {}]", resp);
        }

        cn.hutool.json.JSONObject object = JSONUtil.parseObj(resp);

        if (ResponseCode.SUCC.equals(object.getInt(ResponseCode.RET))) {
            return object.get("data", TempPowerCheckResult.class);
        }

        return TempPowerCheckResult.cannotTempPower(object.getStr("msg"));
    }

    /**
     * 临时通电
     */
    public static void powerOn(Map<String, Object> params) {
        String tempPower = UqbikeManagerConfig.clientsite + "/terControl/rpc/tempPower.do";

        if (log.isInfoEnabled()) {
            log.info("[UQHttpClient][powerOn][params: {}]", params);
        }

        String resp = UQHttpUtil.sendPut(tempPower, params);

        if (log.isInfoEnabled()) {
            log.info("[UQHttpClient][powerOn][result: {}]", resp);
        }

        JsonResult<Boolean> jsonResult = JSONUtil.toBean(resp, new TypeReference<JsonResult<Boolean>>() {
        }, true);

        if (ResponseCode.FAIL.equals(jsonResult.getRet())) {
            throw new BaseException(jsonResult.getMsg());
        }
    }


    public static void main(String[] args) {
        //System.out.println(operationalDataToMain(100001, "11952", "2022-11-01 00:00:00", "2022-11-18 00:00:00"));
//        System.out.println(getVert("019170018", 1, 200530, 113.94476666666667, 22.55285));
    }
}